﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using xTrackEmailer_Service.Properties;
using xTrackEmailer_Core;
using System.IO;

namespace xTrackEmailer_Service
{
    public partial class Service : ServiceBase
    {
        #region Members
        private Thread m_MainThread;
        private xTrackEmailer_Core.SendMail m_MailSender;
        private bool m_Running = false;
        #endregion

        #region C-TOR
        public Service()
        {
            InitializeComponent();

            m_MailSender = new SendMail();

            m_MainThread = new Thread(new ThreadStart(ThreadMethod));
            m_MainThread.IsBackground = true;
        }
        #endregion

        #region Methods
        protected override void OnStart(string[] args)
        {
            m_Running = true;
            m_MainThread.Start();
        }

        protected override void OnStop()
        {
            m_Running = false;
            m_MainThread.Abort();
        }

        private void ThreadMethod()
        {
            int retryAttempts = Settings.Default.RetryAttempts;
            string tempFilesPath = Settings.Default.TempFilesPath;
            if (!tempFilesPath.EndsWith("\\") && !string.IsNullOrEmpty(tempFilesPath))
                tempFilesPath += "\\";
            Thread.Sleep(5000);

            while (m_Running)
            {
                using (DBDataContext m_DB = new DBDataContext(Settings.Default.ConnectionString))
                {
                    if (!m_Running)
                        return;

                    List<EmailsToSend> emails = m_DB.EmailsToSends.Where(p => !p.Sent && p.RetryCount < retryAttempts).ToList();

                    foreach (EmailsToSend email in emails)
                    {
                        if (!m_Running)
                            return;

                        List<Emails_Receiver> receivers = m_DB.Emails_Receivers.Where(p => p.idEmail == email.Id && p.Active).ToList();
                        if (receivers.Count == 0)
                        {
                            email.RetryCount++;
                            email.SendError = "Nu are destinatar.";
                            m_DB.SubmitChanges();
                            continue;
                        }

                        List<string> attachmentsFiles = new List<string>();
                        List<Emails_Attachment> attachments = m_DB.Emails_Attachments.Where(p => p.idEmail == email.Id && p.Active).ToList();
                        if (attachments.Count > 0)
                        {
                            if (!string.IsNullOrEmpty(tempFilesPath) &&
                                Directory.Exists(tempFilesPath))
                                Directory.CreateDirectory(tempFilesPath);

                            foreach (Emails_Attachment att in attachments)
                            {
                                string fileName = string.Format("{0}{1}_{2}", tempFilesPath, att.Id, att.FileName);
                                if (!File.Exists(fileName))
                                    using (FileStream fs = File.Create(fileName))
                                    {
                                        fs.Write(att.Attachment.ToArray(), 0, att.Attachment.Length);
                                        fs.Close();
                                    }

                                attachmentsFiles.Add(fileName);
                            }
                        }

                        Exception ex = m_MailSender.Send(
                               email.From,
                               receivers.Select(p => p.To.Trim()).Distinct().ToList(),
                               email.Description,
                               email.Content,
                               true,
                               attachmentsFiles);

                        if (ex != null)
                        {
                            email.SendError = ex.Message;
                            email.RetryCount++;
                        }
                        else
                        {
                            email.Sent = true;
                            email.SentDate = DateTime.Now;
                        }
                        m_DB.SubmitChanges();

                        if (!m_Running)
                            return;
                    }
                }
                for (int i = 0; i < Settings.Default.SendInterval && m_Running; i++)
                    Thread.Sleep(1000);
            }
        }
        #endregion
    }
}
